<template>
  <div class="xtx-numbox">
    <div class="label">数量</div>
    <div class="numbox">
      <a href="javascript:;" @click="des">-</a>
      <input type="text" readonly :value="count" />
      <a href="javascript:;" @click="ins">+</a>
    </div>
  </div>
</template>

<script>
// 步骤
// 1. 实现基础增减逻辑
// 思路: 准备一个响应式的number类型数据 点+号 count++ 点-号 count--
// 2. 通过传入不同的props控制最大值和最小值
// 思路: 增加俩个props选项 一个最大值 一个是最小值 然后在增加回调中做判断
// 3. v-model双向绑定优化 [组件身上如果绑定一个v-model]
// 组件的作用？
// 父组件中拿到当前子组件中的count值最后把它当成接口参数传给后端！- 子传父 emit
// 子组件一上来初始化的时候value值由父组件决定它到底是几 - 父传子 prop
// 结论:要想实现以上的需求 通过传统的父子通信完全没有问题 可以 但是有些许麻烦 如何简化 -> v-model
// 父子通信是v-model基础 v-model是语法糖 父子通信必会的

// 认识v-model并做实现
// <Number v-model="count"/>
// 1. 绑定了一个名称为 modelValue的 prop属性  <Number :model-value="count"/>
// 2. 绑定了一个名称为 update:modelValue的自定义事件 <Number @update:modelValue="cb"/>
// 3. 当你在子组件中通过emit方法触发update:modelValue事件的时候 自动把事件触发时传入的数据
// 同步到v-model等于号后面的数据count身上  count.value = 事件参数

// 总结一个套路 所有表单类组件封装的通用逻辑 v-model

// 1. 实现父同步到子  1. 子组件中初始化的时候以父组件传入的modelValue为主 + 2.watch监听modelValue变化再次同步
// 2. 子同步到父  触发自定义事件update:modelValue  emit('update:modelValue','最新值')

import { ref, watch } from 'vue'
export default {
  name: 'XtxNumber',
  props: {
    max: {
      type: Number
    },
    min: {
      type: Number,
      default: 1
    },
    modelValue: {
      type: Number
    }
  },
  setup (props, ctx) {
    const count = ref(props.modelValue)
    // 如果传入的modelValue发生了变化 count会变吗？ watch
    watch(
      () => props.modelValue,
      () => {
        count.value = props.modelValue
      }
    )
    // 增加
    const ins = () => {
      if (count.value === props.max) {
        return
      }
      count.value++
      // 触发事件进行数据同步
      ctx.emit('update:modelValue', count.value)
    }
    // 减少
    const des = () => {
      if (count.value === props.min) {
        return
      }
      count.value--
      // 触发事件进行数据同步
      ctx.emit('update:modelValue', count.value)
    }
    return {
      count,
      ins,
      des
    }
  }
}
</script>

<style scoped lang="less">
.xtx-numbox {
  display: flex;
  align-items: center;
  .label {
    width: 60px;
    color: #999;
    padding-left: 10px;
  }
  .numbox {
    width: 120px;
    height: 30px;
    border: 1px solid #e4e4e4;
    display: flex;
    > a {
      width: 29px;
      line-height: 28px;
      text-align: center;
      background: #f8f8f8;
      font-size: 16px;
      color: #666;
      &:first-of-type {
        border-right: 1px solid #e4e4e4;
      }
      &:last-of-type {
        border-left: 1px solid #e4e4e4;
      }
    }
    > input {
      width: 60px;
      padding: 0 5px;
      text-align: center;
      color: #666;
    }
  }
}
</style>
